home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / StereoScope / Source / CubeView.m < prev    next >
Text File  |  1994-04-01  |  7KB  |  300 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "CubeView.h"
  5. #import "dotAt.h"
  6. #import <stdlib.h>
  7. #import <strings.h>
  8. #import <stdio.h>
  9. #import <dpsclient/wraps.h>
  10. #import <dpsclient/dpsNeXT.h>
  11. #import <appkit/NXBitmapImageRep.h>
  12. #import <appkit/Control.h>
  13. #import <appkit/Form.h>
  14. #import <appkit/OpenPanel.h>
  15. #import <appkit/Pasteboard.h>
  16. #import <appkit/Application.h>
  17. #import <streams/streams.h>
  18. #import <math.h>
  19. #define MAXLINE 10000
  20. #define MAXNUM  10000
  21. #define rad_to_deg  (180./M_PI)
  22. #define TRUE 0
  23. #define FALSE !TRUE
  24. #define defRadius 0.01
  25. extern id NXApp;
  26.  
  27. @implementation CubeView
  28.  
  29. - initFrame:(const NXRect *) frameRect
  30. {
  31.   self = [super initFrame: frameRect];
  32.   [self initialize];
  33.     [self setCube:YES];
  34.     [self setAxes:NO];
  35.   return self;
  36. }
  37.  
  38. - initialize
  39. {
  40.   [self setDrawSize:(NXCoord) 2:(NXCoord) 2];
  41.   [self setDrawOrigin:(NXCoord) -1:(NXCoord) -1];
  42.   PSonly = NO;
  43.   vm = [AzimuthMat new];
  44.                 // establish the ops array and
  45.                 // bounding box for DPSDoUserPath()
  46.   ops[0] = dps_moveto; ops[1] = 32 + 15; ops[2] = dps_lineto;
  47.   boundingBox[0] = bounds.origin.x;
  48.   boundingBox[1] = bounds.origin.y;
  49.   boundingBox[2] = bounds.origin.x + bounds.size.width;
  50.   boundingBox[3] = bounds.origin.y + bounds.size.height;
  51. /*
  52.   [self setAutosizing:NX_WIDTHSIZABLE || NX_HEIGHTSIZABLE];
  53. */
  54. /*
  55.   [self reScale:self];
  56. */
  57.   return self;
  58. }
  59.  
  60. - showError:(char *)errorMessage
  61. {
  62.   NXRunAlertPanel("Error", errorMessage, "OK", NULL, NULL);
  63.   return self;
  64. }
  65.  
  66. - clear:sender
  67. {
  68.   [self reScale:self];
  69.   [self Reset:self];
  70.   [self display];
  71.   return self;
  72.  
  73. }
  74.  
  75. - Reset:sender
  76. {
  77.   [vm setTheta:0.];
  78.   [vm setPhi:0.];
  79.   [vm setdist:2.0];
  80.   [self display];
  81.   return self;
  82. }
  83.  
  84. - printPSCode:sender
  85. {
  86.   PSonly = YES;
  87.   return self;
  88. }
  89.  
  90. - setTheta:(float)floatValue
  91. {
  92.   [vm setTheta:floatValue];
  93.   [self display];
  94.   return self;
  95. }
  96.  
  97. - setPhi:(float)floatValue
  98. {
  99.   [vm setPhi:-floatValue];
  100.   [self display];
  101.   return self;
  102. }
  103.  
  104. - setdist:(float)floatValue
  105. {
  106.   [vm setdist:floatValue];
  107.   [self display];
  108.   return self;
  109. }
  110.  
  111. - setCube:(int)intValue
  112. {
  113.     showCube = intValue;
  114.   [self display];
  115.     return self;
  116. }
  117.  
  118. - setAxes:(int)intValue
  119. {
  120.     showAxes = intValue;
  121.   [self display];
  122.     return self;
  123. }
  124.  
  125. - toggleCube:sender
  126. {
  127.   showCube = showCube ? NO : YES;
  128.   [self display];
  129.   return self;
  130. }
  131.  
  132. - toggleAxes:sender
  133. {
  134.   showAxes = showAxes ? NO : YES;
  135.   [self display];
  136.   return self;
  137. }
  138.  
  139. - reScale:sender
  140. {
  141.   float maxval[3], minval[3], limits[6], *fpt;
  142.   datapoints **all_lines = toshow, *thisline;
  143.   short int i, count;
  144.  
  145.   if (*all_lines == (datapoints *) NULL) { /* no data - set to defaults */
  146.     limits[0] = limits[1] = limits[2] = 0.;
  147.     limits[3] = limits[4] = limits[5] = 1.;
  148.     [self setlimits:limits];
  149.     return self;
  150.   }
  151.   for(i = 0; i < 3; i++)
  152.     minval[i] = maxval[i] = *((*all_lines)->displayed[i]);
  153.   while (thisline = *all_lines++) {
  154.     for(i = 0; i < 3; i++) {
  155.       count = thisline->npts;
  156.       fpt = thisline->displayed[i];
  157.       while (count--) {
  158.     if (*fpt < minval[i]) minval[i] = *fpt;
  159.     if (*fpt > maxval[i]) maxval[i] = *fpt;
  160.     fpt++;
  161.       }
  162.     }
  163.   }
  164.   for(i = 0; i < 3; i++) {
  165.     if (minval[i] >= maxval[i]) minval[i] = maxval[i] - 1;
  166.     limits[i] = minval[i] - 0.035*(maxval[i] - minval[i]);
  167.     limits[i + 3] = maxval[i] + 0.035*(maxval[i] - minval[i]);
  168.   }
  169.   [self setlimits:limits];
  170.   return self;
  171. }
  172.  
  173.  
  174.  
  175. static int x_seq[] = {0,3,3,0,0,0,3,3,0,0,3,3,3,3,0,0};
  176. static int y_seq[] = {1,1,4,4,1,1,1,4,4,1,1,1,4,4,4,4};
  177. static int z_seq[] = {2,2,2,2,2,5,5,5,5,5,5,2,2,5,5,2};
  178.  
  179. -setlimits:(float *)newlimits
  180. {
  181.   int i, n, tickdir;
  182.   float tick, width;
  183.  
  184.   for (n = 0; n < 16; n++) {    /* create cube */
  185.     cube[0][n] = newlimits[x_seq[n]];
  186.     cube[1][n] = newlimits[y_seq[n]];
  187.     cube[2][n] = newlimits[z_seq[n]];
  188.   }
  189.   for (n = 0; n < 54; n++) {    /* create axes */
  190.     axes[0][n] = newlimits[0];
  191.     axes[1][n] = newlimits[1];
  192.     axes[2][n] = newlimits[2];
  193.   }
  194.   for (i = 0; i < 3; i++) {
  195.     tickdir = (i == 0) ? 1 : 0;
  196.     tick = 0.03 * (newlimits[tickdir + 3] - newlimits[tickdir]);
  197.     width = newlimits[i + 3] - newlimits[i];
  198.     n = 18 * i;
  199.     axes[i][n+1] = axes[i][n+2] = axes[i][n+3] = axes[i][n+4] =
  200.       newlimits[i] + 0.25 * width;
  201.     axes[i][n+5] = axes[i][n+6] = axes[i][n+7] = axes[i][n+8] =
  202.       newlimits[i] + 0.5 * width;
  203.     axes[i][n+9] = axes[i][n+10] = axes[i][n+11] = axes[i][n+12] =
  204.       newlimits[i] + 0.75 * width;
  205.     axes[i][n+13] = axes[i][n+17] = newlimits[i] + 0.87 * width;
  206.     axes[i][n+14] = axes[i][n+16] = newlimits[i] + 0.84 * width;
  207.     axes[i][n+15] = newlimits[i] + width;
  208.     axes[tickdir][n+2] = axes[tickdir][n+6] = axes[tickdir][n+10] =
  209.       axes[tickdir][n+14] = newlimits[tickdir] + tick;
  210.     axes[tickdir][n+3] = axes[tickdir][n+7] = axes[tickdir][n+11] =
  211.       axes[tickdir][n+16] = newlimits[tickdir] - tick;
  212.   }
  213.   [vm setlimits:newlimits];
  214. /*  [self Reset:self];
  215. */
  216.   return self;
  217. }
  218.  
  219. - getStruct:(datapoints ***)dptr:(int) max_p:(float **)p
  220. {
  221.  
  222.     toshow = *dptr;
  223.     max_path = max_p;
  224.     path = *p;
  225.     
  226. /*
  227. {
  228.     datapoints **all_data, *thesedata;
  229.     int count;
  230.     
  231.     all_data = toshow;
  232.     count = 0;
  233.     printf("CubeView: data structure toshow\n");
  234.     while ((thesedata = *all_data++) != (datapoints *) NULL) {
  235.         printf("count = %d, npts = %d, type = %d\n",
  236.             count++, thesedata->npts, thesedata->type);
  237.             if (count > 10) break;
  238.             }
  239.  
  240. }
  241. */
  242.     [self reScale:self];
  243.     return self;
  244. }
  245.  
  246. - drawSelf:(NXRect*)r :(int)c
  247. {
  248.   datapoints **all_lines = toshow, *thisline;
  249.   float radius = defRadius;
  250.   float    shade = NX_BLACK;
  251.   
  252.   NXEraseRect(&bounds);
  253. /*
  254.  *    We would set defaults, but overide if data is not null;
  255.  *
  256. */
  257.   PSsetgray(NX_BLACK);
  258.   PSsetlinewidth(0.0);
  259.   if (showCube) {
  260.     ops[1] = 32 + 16 - 1;
  261.     DPSDoUserPath ([vm as_DPSpath :16 :cube[0] :cube[1] :cube[2] :path],
  262.            32, dps_float, ops, 3, boundingBox, dps_ustroke);
  263.   }
  264.   if (showAxes) {
  265.     ops[1] = 32 + 54 - 1;
  266.     DPSDoUserPath ([vm as_DPSpath :54 :axes[0] :axes[1] :axes[2] :path],
  267.            108, dps_float, ops, 3, boundingBox, dps_ustroke);
  268.   }
  269.   while((thisline = *all_lines++) != (datapoints *) NULL) {
  270.     if (thisline->type & 0x1) {    /* draw the line */
  271.       ops[1] = thisline->npts + 32 - 1;
  272.       DPSDoUserPath([vm as_DPSpath :thisline->npts
  273.              :(thisline->displayed)[0] :(thisline->displayed)[1]
  274.              :(thisline->displayed)[2] :path],
  275.             2*(thisline->npts), dps_float,
  276.             ops, 3, boundingBox, dps_ustroke);
  277.     }
  278.     if (thisline->type & 0x2) {    /* draw points */
  279. /*
  280.  *    Here we pull out thisline->radius and thisline->shade
  281.  *  If they are not the default(?) then set them and pass
  282.  *  Otherwise use default.
  283. */
  284.     if (thisline->radius <= 0.) radius = defRadius;
  285.         else radius = thisline->radius;
  286.     if (thisline->shade < 0.) shade = NX_BLACK;
  287.         else shade = thisline->shade;
  288.         
  289.     dotAtPSonly([vm as_DPSpath :thisline->npts
  290.              :(thisline->displayed)[0] :(thisline->displayed)[1]
  291.              :(thisline->displayed)[2] :path],
  292.             2 *(thisline->npts), radius, shade);
  293.      }
  294.   }
  295.   PSonly = NO;
  296.   return self;
  297. }
  298.  
  299. @end
  300.